package com.jc.common.util;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;

public class HttpUtil {
	private static final RequestConfig	REQUEST_CONFIG	= RequestConfig.copy(RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT).setExpectContinueEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build()).setSocketTimeout(60000).setConnectTimeout(40000).build();

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(HttpUtil.class);
    
	private static RequestConfig getconfig() {
		return REQUEST_CONFIG;
	}

	private static List<NameValuePair> setNameValuePair(Map<String, Object> params) {
		
		List<NameValuePair> paramsList = new LinkedList<NameValuePair>();
		for (String key : params.keySet()) {
			if (params.get(key) == null) {
				paramsList.add(new BasicNameValuePair(key, null));
			} else {
				paramsList.add(new BasicNameValuePair(key, params.get(key).toString()));
			}
		}
		return paramsList;
	}

	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @Title:get
	 * @param url
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url) throws ClientProtocolException, IOException, URISyntaxException {
		return get(url, (List<NameValuePair>) null);
	}

	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @Title:get
	 * @param url
	 * @param params
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, Map<String, Object> params) throws ClientProtocolException, IOException, URISyntaxException {
		if (MapUtils.isEmpty(params)) { return get(url); }
		return get(url, setNameValuePair(params));
	}

	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd>默认编码UTF-8</dd>
	 * </dl>
	 * @Title:get
	 * @param url
	 * @param params
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, List<NameValuePair> params) throws ClientProtocolException, IOException, URISyntaxException {
		return get(url, params, "UTF-8");
	}

	/**
	 * <dl>
	 * 说明：get基础方法
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @Title:get
	 * @param url
	 * @param params
	 * @param defaultCharset 编码格式
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, List<NameValuePair> params, String defaultCharset) throws ClientProtocolException, IOException, URISyntaxException {
		if (defaultCharset == null || defaultCharset.trim().equals("")) {
			defaultCharset = "UTF-8";

		}

		if (url == null || url.trim().equals("")) {
			throw new ClientProtocolException("url is null");
		} else {
			if (params != null && params.size() > 0) {
				String string = EntityUtils.toString(new UrlEncodedFormEntity(params, defaultCharset));
				if (url.indexOf("?") != -1) {
					url += "&" + string;
				} else {
					url += "?" + string;
				}
			}
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		//custom().setDefaultCookieStore(new BasicCookieStore()).setDefaultRequestConfig(getconfig()).build();
		try {
			final HttpGet httpget = new HttpGet(url);
			httpget.setConfig(getconfig());
			CloseableHttpResponse response = httpclient.execute(httpget);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					responseBody = EntityUtils.toString(entity, defaultCharset);
				}
				EntityUtils.consume(entity);
				return responseBody;
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("GET：{} 结果{}", new Object[] { url, responseBody });
			}
		}
	}

	/**
	 * <dl>
	 * 说明：post提交
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @Title:post
	 * @param url
	 * @param params
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException String
	 */
	public static String post(String url, Map<String, Object> params) throws Exception {
		return post(url, setNameValuePair(params));
	}

	/**
	 * <dl>
	 * 说明：post请求
	 * <dt></dt>
	 * <dd>默认编码UTF-8</dd>
	 * </dl>
	 * @author liujinlei
	 * @Title:post
	 * @param url
	 * @param params
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String post(String url, List<NameValuePair> params) throws Exception {
		return post(url, params, "UTF-8");
	}

	/**
	 * <dl>
	 * 说明：post提交基础方法
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @Title:post
	 * @param url
	 * @param params
	 * @param defaultCharset 编码格式
	 * @return String
	 */
	public static String post(String url, List<NameValuePair> params, String defaultCharset) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			if (defaultCharset == null || defaultCharset.trim().equals("")) {
				defaultCharset = "UTF-8";
			}
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(getconfig());
			if (params != null && params.size() > 0) {
				httppost.setEntity(new UrlEncodedFormEntity(params, defaultCharset));
			}
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				//LOGGER.debug("POST：{} 结果{}-参数{}", new Object[] { url, responseBody, params });
			}
		}
	}

	public static String postBody(String url, String body, Charset defaultCharset) throws Exception {
		if (defaultCharset == null) {
			defaultCharset = Charset.forName("UTF-8");
		}
		return postBody(url, URLEncoder.encode(body, defaultCharset.name()));
	}

	public static String postBody(String url, String body, Map<String, Object> requestHeaderParamMap, ContentType bodyContentType) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }
		if (bodyContentType == null) {
			bodyContentType = ContentType.TEXT_HTML;
		}

		if (requestHeaderParamMap != null && requestHeaderParamMap.size() > 0) {
			url = url + "?" + MapUtils.getUrlParamsByMap(requestHeaderParamMap);
		}
		return postBody(url, body, bodyContentType);
	}

	public static String postBody(String url, String body) throws Exception {
		return postBody(url, body, ContentType.TEXT_HTML);
	}

	public static String postBody(String url, String body, ContentType bodyContentType) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }
		if (bodyContentType == null) {
			bodyContentType = ContentType.TEXT_HTML;
		}
		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(getconfig());
			if (StringUtils.isNotEmpty(body)) {
				StringEntity entity = new StringEntity(body, "UTF-8");//解决中文乱码问题   
				//			entity.setContentType(bodyContentType);
				entity.setContentType(bodyContentType.toString());
				httppost.setEntity(entity);
			}
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, "UTF-8");
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("POST：{} body:{}结果{}", new Object[] { url, body, responseBody });
			}
		}

	}

	public static String postJson(String url, String body, Charset defaultCharset) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }
		if (defaultCharset == null) {
			defaultCharset = Charset.forName("UTF-8");
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(getconfig());
			StringEntity entity = new StringEntity(body.toString(), defaultCharset);//解决中文乱码问题    
			//StringEntity entity = new StringEntity(new String(bytes, charsetName), defaultCharset);
			entity.setContentEncoding(defaultCharset.name());
			entity.setContentType("application/json");
			httppost.setEntity(entity);
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("POST：{} 结果{}", new Object[] { url, responseBody });
			}
		}

	}

	
	public static String postJson(String url, byte[] body, Charset defaultCharset) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }
		if (defaultCharset == null) {
			defaultCharset = Charset.forName("UTF-8");
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(getconfig());
		
			StringEntity entity = new StringEntity(new String(body, "UTF-8"), defaultCharset);
			entity.setContentEncoding(defaultCharset.name());
			entity.setContentType("application/json;charset=UTF-8");
			
			httppost.setEntity(entity);
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("POST：{} 结果{}", new Object[] { url, responseBody });
			}
		}

	}
	
	
	
	/**
	 * <dl>
	 * 说明：上传文�??
	 * <dt></dt>
	 * <dd>后台根据fileResources获取文件对象；根据channelSourceType获取文件来源</dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016�??1�??4�?? 下午2:15:29
	 * @Title:postFile
	 * @param url 上传地址
	 * @param targetFile 上传文件对象
	 * @param channelSourceType 文件来源
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException String
	 */
	public static String postFile(String url, File targetFile, String channelSourceType) throws ClientProtocolException, IOException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("channelSourceType", channelSourceType);
		return postFile(url, "fileResources", targetFile, params);
	}

	/**
	 * <dl>
	 * 说明：文件上传基�??方法
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016�??1�??4�?? 下午2:42:10
	 * @Title:postFile
	 * @param url 上传文件地址
	 * @param fileTargetName 上传文件标识
	 * @param targetFile 上传文件
	 * @param params 文件参数
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String postFile(String url, String fileTargetName, File targetFile, Map<String, Object> params) throws ClientProtocolException, IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			if (targetFile == null || !targetFile.exists()) { throw new FileNotFoundException(fileTargetName + " is null"); }
			if (!targetFile.isFile()) { throw new FileNotFoundException(fileTargetName + " is not file."); }

			HttpPost httppost = new HttpPost(url);

			FileBody bin = new FileBody(targetFile);
			MultipartEntityBuilder addPart = MultipartEntityBuilder.create().addPart(fileTargetName, bin);
			for (String key : params.keySet()) {
				if (params.get(key) != null) {
					addPart.addTextBody(key, params.get(key).toString(), ContentType.TEXT_PLAIN);
				}
			}
			httppost.setEntity(addPart.build());

			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				String responseBody = null;
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} finally {
				response.close();
				targetFile = null;
			}
		} finally {
			httpclient.close();
		}
	}

	/**
	 * <dl>
	 * 说明：上传文�??
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016�??1�??4�?? 下午2:43:13
	 * @Title:postFile
	 * @param url 上传文件地址
	 * @param fileTargetName 上传文件标识
	 * @param targetFilePath 上传文件路径
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String postFile(String url, String fileTargetName, String targetFilePath) throws ClientProtocolException, IOException {
		if (targetFilePath == null || targetFilePath.trim().equals("")) { throw new FileNotFoundException(targetFilePath + " is null"); }
		return postFile(url, fileTargetName, new File(targetFilePath), (Map<String, Object>) null);
	}

	public static String postJson(String url, List<Header> headers, String body, Charset defaultCharset) throws Exception {
		long currentTimeMillis = System.currentTimeMillis();
		if (url == null || url.trim().equals("")) {
			throw new NullPointerException("url is null");
		}
		if (defaultCharset == null) {
			defaultCharset = Charset.forName("UTF-8");
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			//httppost.setHeader(header);
			for(Header header : headers) {
				httppost.addHeader(header);
			}
			httppost.setConfig(getconfig());
			StringEntity entity = new StringEntity(body.toString(), defaultCharset);// 解决中文乱码问题
			entity.setContentEncoding(defaultCharset.name());
			entity.setContentType("application/json");
			httppost.setEntity(entity);
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isInfoEnabled()) {
				LOGGER.info("\n POST:{} \n body:{}\n 结果:{}\n 耗时 :{}", new Object[] { url, body, responseBody, System.currentTimeMillis() - currentTimeMillis });
			}
		}

	}

	public static String postXML(String url, List<Header> headers, String body, Charset defaultCharset) throws Exception {
		long currentTimeMillis = System.currentTimeMillis();
		if (url == null || url.trim().equals("")) {
			throw new NullPointerException("url is null");
		}
		if (defaultCharset == null) {
			defaultCharset = Charset.forName("UTF-8");
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			//httppost.setHeader(header);
			for(Header header : headers) {
				httppost.addHeader(header);
			}
			httppost.setConfig(getconfig());
			StringEntity entity = new StringEntity(body.toString(), defaultCharset);// 解决中文乱码问题
			entity.setContentEncoding(defaultCharset.name());
			entity.setContentType("text/xml");
			httppost.setEntity(entity);
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
			if (LOGGER.isInfoEnabled()) {
				LOGGER.info("\n POST:{} \n body:{}\n 结果:{}\n 耗时 :{}", new Object[] { url, body, responseBody, System.currentTimeMillis() - currentTimeMillis });
			}
		}

	}
	
	
	
	public static void main(String[] args) {
		try {
			Map<String, Object> hashMap = new HashMap<String, Object>();
			hashMap.put("user", "SQHZP");
			hashMap.put("passwd", "148066fbff91da5628594931a53573fc");
			hashMap.put("msg", "ceshi发�?�新版http");
			hashMap.put("mobs", "18017978790");

			String post = HttpUtil.post("http://192.168.50.62:9900/iwms/port/job/productStore/backup", hashMap);
			//			System.out.println(post);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
